package org.budo.mongo.wrapper;

import java.util.List;

import org.bson.codecs.configuration.CodecRegistry;
import org.bson.conversions.Bson;
import org.budo.mongo.filter.MongoFilter;
import org.budo.mongo.filter.MongoFilterChain;
import org.budo.mongo.filter.MongoFilterChainImpl;

import com.mongodb.MongoNamespace;
import com.mongodb.ReadConcern;
import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern;
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.DistinctIterable;
import com.mongodb.client.FindIterable;
import com.mongodb.client.ListIndexesIterable;
import com.mongodb.client.MapReduceIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.BulkWriteOptions;
import com.mongodb.client.model.CountOptions;
import com.mongodb.client.model.DeleteOptions;
import com.mongodb.client.model.FindOneAndDeleteOptions;
import com.mongodb.client.model.FindOneAndReplaceOptions;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.model.InsertManyOptions;
import com.mongodb.client.model.InsertOneOptions;
import com.mongodb.client.model.RenameCollectionOptions;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;

@SuppressWarnings("rawtypes")
public class MongoCollectionWrapper implements MongoCollection {
    private MongoFilterChain filterChain;

    private MongoCollection mongoCollection;

    public MongoCollectionWrapper(List<MongoFilter> filters, MongoCollection mongoCollection) {
        this.filterChain = new MongoFilterChainImpl(filters);
        this.mongoCollection = mongoCollection;
    }

    @Override
    public AggregateIterable aggregate(List $0, Class $1) {
        return filterChain.mongoCollection_aggregate(this.mongoCollection, $0, $1);
    }

    @Override
    public AggregateIterable aggregate(List $0) {
        return filterChain.mongoCollection_aggregate(this.mongoCollection, $0);
    }

    @Override
    public BulkWriteResult bulkWrite(List $0) {
        return filterChain.mongoCollection_bulkWrite(this.mongoCollection, $0);
    }

    @Override
    public BulkWriteResult bulkWrite(List $0, BulkWriteOptions $1) {
        return filterChain.mongoCollection_bulkWrite(this.mongoCollection, $0, $1);
    }

    @Override
    public long count() {
        return filterChain.mongoCollection_count(this.mongoCollection);
    }

    @Override
    public long count(Bson $0) {
        return filterChain.mongoCollection_count(this.mongoCollection, $0);
    }

    @Override
    public long count(Bson $0, CountOptions $1) {
        return filterChain.mongoCollection_count(this.mongoCollection, $0, $1);
    }

    @Override
    public String createIndex(Bson $0) {
        return filterChain.mongoCollection_createIndex(this.mongoCollection, $0);
    }

    @Override
    public String createIndex(Bson $0, IndexOptions $1) {
        return filterChain.mongoCollection_createIndex(this.mongoCollection, $0, $1);
    }

    @Override
    public List createIndexes(List $0) {
        return filterChain.mongoCollection_createIndexes(this.mongoCollection, $0);
    }

    @Override
    public DeleteResult deleteMany(Bson $0) {
        return filterChain.mongoCollection_deleteMany(this.mongoCollection, $0);
    }

    @Override
    public DeleteResult deleteMany(Bson $0, DeleteOptions $1) {
        return filterChain.mongoCollection_deleteMany(this.mongoCollection, $0, $1);
    }

    @Override
    public DeleteResult deleteOne(Bson $0) {
        return filterChain.mongoCollection_deleteOne(this.mongoCollection, $0);
    }

    @Override
    public DeleteResult deleteOne(Bson $0, DeleteOptions $1) {
        return filterChain.mongoCollection_deleteOne(this.mongoCollection, $0, $1);
    }

    @Override
    public DistinctIterable distinct(String $0, Class $1) {
        return filterChain.mongoCollection_distinct(this.mongoCollection, $0, $1);
    }

    @Override
    public DistinctIterable distinct(String $0, Bson $1, Class $2) {
        return filterChain.mongoCollection_distinct(this.mongoCollection, $0, $1, $2);
    }

    @Override
    public void drop() {
        filterChain.mongoCollection_drop(this.mongoCollection);
    }

    @Override
    public void dropIndex(String $0) {
        filterChain.mongoCollection_dropIndex(this.mongoCollection, $0);
    }

    @Override
    public void dropIndex(Bson $0) {
        filterChain.mongoCollection_dropIndex(this.mongoCollection, $0);
    }

    @Override
    public void dropIndexes() {
        filterChain.mongoCollection_dropIndexes(this.mongoCollection);
    }

    @Override
    public FindIterable find(Class $0) {
        return filterChain.mongoCollection_find(this.mongoCollection, $0);
    }

    @Override
    public FindIterable find(Bson $0, Class $1) {
        return filterChain.mongoCollection_find(this.mongoCollection, $0, $1);
    }

    @Override
    public FindIterable find() {
        return filterChain.mongoCollection_find(this.mongoCollection);
    }

    @Override
    public FindIterable find(Bson $0) {
        return filterChain.mongoCollection_find(this.mongoCollection, $0);
    }

    @Override
    public Object findOneAndDelete(Bson $0) {
        return filterChain.mongoCollection_findOneAndDelete(this.mongoCollection, $0);
    }

    @Override
    public Object findOneAndDelete(Bson $0, FindOneAndDeleteOptions $1) {
        return filterChain.mongoCollection_findOneAndDelete(this.mongoCollection, $0, $1);
    }

    @Override
    public Object findOneAndReplace(Bson $0, Object $1) {
        return filterChain.mongoCollection_findOneAndReplace(this.mongoCollection, $0, $1);
    }

    @Override
    public Object findOneAndReplace(Bson $0, Object $1, FindOneAndReplaceOptions $2) {
        return filterChain.mongoCollection_findOneAndReplace(this.mongoCollection, $0, $1, $2);
    }

    @Override
    public Object findOneAndUpdate(Bson $0, Bson $1) {
        return filterChain.mongoCollection_findOneAndUpdate(this.mongoCollection, $0, $1);
    }

    @Override
    public Object findOneAndUpdate(Bson $0, Bson $1, FindOneAndUpdateOptions $2) {
        return filterChain.mongoCollection_findOneAndUpdate(this.mongoCollection, $0, $1, $2);
    }

    @Override
    public CodecRegistry getCodecRegistry() {
        return filterChain.mongoCollection_getCodecRegistry(this.mongoCollection);
    }

    @Override
    public Class getDocumentClass() {
        return filterChain.mongoCollection_getDocumentClass(this.mongoCollection);
    }

    @Override
    public MongoNamespace getNamespace() {
        return filterChain.mongoCollection_getNamespace(this.mongoCollection);
    }

    @Override
    public ReadConcern getReadConcern() {
        return filterChain.mongoCollection_getReadConcern(this.mongoCollection);
    }

    @Override
    public ReadPreference getReadPreference() {
        return filterChain.mongoCollection_getReadPreference(this.mongoCollection);
    }

    @Override
    public WriteConcern getWriteConcern() {
        return filterChain.mongoCollection_getWriteConcern(this.mongoCollection);
    }

    @Override
    public void insertMany(List $0) {
        filterChain.mongoCollection_insertMany(this.mongoCollection, $0);
    }

    @Override
    public void insertMany(List $0, InsertManyOptions $1) {
        filterChain.mongoCollection_insertMany(this.mongoCollection, $0, $1);
    }

    @Override
    public void insertOne(Object $0) {
        filterChain.mongoCollection_insertOne(this.mongoCollection, $0);
    }

    @Override
    public void insertOne(Object $0, InsertOneOptions $1) {
        filterChain.mongoCollection_insertOne(this.mongoCollection, $0, $1);
    }

    @Override
    public ListIndexesIterable listIndexes(Class $0) {
        return filterChain.mongoCollection_listIndexes(this.mongoCollection, $0);
    }

    @Override
    public ListIndexesIterable listIndexes() {
        return filterChain.mongoCollection_listIndexes(this.mongoCollection);
    }

    @Override
    public MapReduceIterable mapReduce(String $0, String $1, Class $2) {
        return filterChain.mongoCollection_mapReduce(this.mongoCollection, $0, $1, $2);
    }

    @Override
    public MapReduceIterable mapReduce(String $0, String $1) {
        return filterChain.mongoCollection_mapReduce(this.mongoCollection, $0, $1);
    }

    @Override
    public void renameCollection(MongoNamespace $0) {
        filterChain.mongoCollection_renameCollection(this.mongoCollection, $0);
    }

    @Override
    public void renameCollection(MongoNamespace $0, RenameCollectionOptions $1) {
        filterChain.mongoCollection_renameCollection(this.mongoCollection, $0, $1);
    }

    @Override
    public UpdateResult replaceOne(Bson $0, Object $1) {
        return filterChain.mongoCollection_replaceOne(this.mongoCollection, $0, $1);
    }

    @Override
    public UpdateResult replaceOne(Bson $0, Object $1, UpdateOptions $2) {
        return filterChain.mongoCollection_replaceOne(this.mongoCollection, $0, $1, $2);
    }

    @Override
    public UpdateResult updateMany(Bson $0, Bson $1) {
        return filterChain.mongoCollection_updateMany(this.mongoCollection, $0, $1);
    }

    @Override
    public UpdateResult updateMany(Bson $0, Bson $1, UpdateOptions $2) {
        return filterChain.mongoCollection_updateMany(this.mongoCollection, $0, $1, $2);
    }

    @Override
    public UpdateResult updateOne(Bson $0, Bson $1) {
        return filterChain.mongoCollection_updateOne(this.mongoCollection, $0, $1);
    }

    @Override
    public UpdateResult updateOne(Bson $0, Bson $1, UpdateOptions $2) {
        return filterChain.mongoCollection_updateOne(this.mongoCollection, $0, $1, $2);
    }

    @Override
    public MongoCollection withCodecRegistry(CodecRegistry $0) {
        return filterChain.mongoCollection_withCodecRegistry(this.mongoCollection, $0);
    }

    @Override
    public MongoCollection withDocumentClass(Class $0) {
        return filterChain.mongoCollection_withDocumentClass(this.mongoCollection, $0);
    }

    @Override
    public MongoCollection withReadConcern(ReadConcern $0) {
        return filterChain.mongoCollection_withReadConcern(this.mongoCollection, $0);
    }

    @Override
    public MongoCollection withReadPreference(ReadPreference $0) {
        return filterChain.mongoCollection_withReadPreference(this.mongoCollection, $0);
    }

    @Override
    public MongoCollection withWriteConcern(WriteConcern $0) {
        return filterChain.mongoCollection_withWriteConcern(this.mongoCollection, $0);
    }

}